//  Inside Microsoft Exchange 2007 Web Services 
//  Chapter 21
//
//  Copyright (c) 2007 David Sterling, Ben Spain, Mark Taylor, Huw Upshall, Michael Mainer.  
//  All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using ProxyHelpers.EWS;

namespace CreateGetUserAvailRequest
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeServiceBinding binding = new ExchangeServiceBinding();
            binding.Url = @"https://yourServer/ews/Exchange.asmx";
            binding.Credentials = new NetworkCredential(
                "username",
                "password",
                "domain");

            EmailAddress organizer = new EmailAddress();
            organizer.Address = "ken.malcolmson@constoso.com";
            EmailAddress attendee = new EmailAddress();
            attendee.Address = "tina.makovec@contoso.com";
            EmailAddress attendee2 = new EmailAddress();
            attendee2.Address = "phyllis.harris@contoso.com";

            GetUserAvailabilityRequestType request = CreateGetUserAvailRequest(
                DateTime.Now.AddDays(1d),
                organizer,
                new EmailAddress[] { attendee, attendee2 });
        }

        /// <summary>
        /// Creates a GetUserAvailabilityRequest instance for an organizer 
        /// and attendees, getting both Free/Busy informaiton and Suggestions for
        /// the entire meeting day. (Listing 21-5)
        /// </summary>
        /// <param name="organizer">Email address of the organizer</param>
        /// <param name="attendees">Array of email addresses for attendees</param>
        /// <returns>GetUserAvailabilityRequest instance.</returns>
        public static GetUserAvailabilityRequestType CreateGetUserAvailRequest(
            DateTime meetingDayAndTime,
            EmailAddress organizer,
            EmailAddress[] attendees)
        {
            // Create a TimeZone structure representing Pacific Standard Time.
            //
            SerializableTimeZone timeZone = new SerializableTimeZone();
            timeZone.Bias = 480;
            timeZone.StandardTime = new SerializableTimeZoneTime();
            timeZone.StandardTime.Bias = 0;
            timeZone.StandardTime.Time = "02:00:00";
            timeZone.StandardTime.DayOrder = 1;
            timeZone.StandardTime.DayOfWeek = DayOfWeekType.Sunday.ToString();
            timeZone.StandardTime.Month = 11;
            timeZone.DaylightTime = new SerializableTimeZoneTime();
            timeZone.DaylightTime.Bias = -60;
            timeZone.DaylightTime.Time = "02:00:00";
            timeZone.DaylightTime.DayOrder = 2;
            timeZone.DaylightTime.DayOfWeek = DayOfWeekType.Sunday.ToString();
            timeZone.DaylightTime.Month = 3;

            // Create the Mailbox array for all attendees
            //
            MailboxData[] mailboxes = new MailboxData[attendees.Length + 1];
            for (int x = 0; x < mailboxes.Length; x++)
            {
                mailboxes[x] = new MailboxData();

                if (x == 0)
                {
                    mailboxes[x].Email = organizer;
                    mailboxes[x].AttendeeType = MeetingAttendeeType.Organizer;
                }
                else
                {
                    mailboxes[x].Email = attendees[x - 1];
                    mailboxes[x].AttendeeType = MeetingAttendeeType.Required;
                }
            }

            // Configure the 24-hour window and details for Free/Busy 
            // information.
            //
            Duration duration = new Duration();
            duration.StartTime = new DateTime(
                meetingDayAndTime.Year,
                meetingDayAndTime.Month,
                meetingDayAndTime.Day,
                0,
                0,
                0,
                DateTimeKind.Unspecified);
            duration.EndTime = duration.StartTime.AddDays(1);

            FreeBusyViewOptionsType freeBusyViewOpts =
                new FreeBusyViewOptionsType();
            freeBusyViewOpts.TimeWindow = duration;
            freeBusyViewOpts.RequestedView = FreeBusyViewType.DetailedMerged;
            freeBusyViewOpts.RequestedViewSpecified = true;
            freeBusyViewOpts.MergedFreeBusyIntervalInMinutes = 30;
            freeBusyViewOpts.MergedFreeBusyIntervalInMinutesSpecified = true;

            // Configure the suggestions view options.
            //
            SuggestionsViewOptionsType suggestionsViewOpts =
                new SuggestionsViewOptionsType();
            suggestionsViewOpts.CurrentMeetingTime = meetingDayAndTime;
            suggestionsViewOpts.CurrentMeetingTimeSpecified = true;
            suggestionsViewOpts.MeetingDurationInMinutes = 60;
            suggestionsViewOpts.MeetingDurationInMinutesSpecified = true;
            suggestionsViewOpts.MaximumResultsByDay = 3;
            suggestionsViewOpts.MaximumResultsByDaySpecified = true;

            // The server enforces that the time window for suggestions must be
            // less than or equal to the time window for free/busy information.
            // Therefore, setting both time windows to be the same duration 
            // makes sense.
            //
            suggestionsViewOpts.DetailedSuggestionsWindow = duration;

            // Prepare the request
            //
            GetUserAvailabilityRequestType getUserAvailRequest =
                new GetUserAvailabilityRequestType();
            getUserAvailRequest.TimeZone = timeZone;
            getUserAvailRequest.FreeBusyViewOptions = freeBusyViewOpts;
            getUserAvailRequest.MailboxDataArray = mailboxes;
            getUserAvailRequest.SuggestionsViewOptions = suggestionsViewOpts;

            return getUserAvailRequest;
        }

    }
}
